﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;

namespace IsAvailBr
{
    public class IsAvailServico
    {
        #region Campos
        protected Socket _socket;
        protected IsAvailCookie _cookie; 
        #endregion

        #region Factories
        protected void ConstruirConexao()
        {
            IPHostEntry hostEntry = Dns.GetHostEntry("whois.registro.br");
            foreach (IPAddress address in hostEntry.AddressList)
            {
                IPEndPoint endpoint = new IPEndPoint(address, 43);
                Socket tempSocket = new Socket(endpoint.AddressFamily, SocketType.Dgram, ProtocolType.Udp);
                tempSocket.Connect(endpoint);
                if (tempSocket.Connected)
                {
                    _socket = tempSocket;
                    break;
                }
            }
            _socket.ReceiveTimeout = 10000;
        }

        public IsAvailServico()
        {
            ConstruirConexao();
        } 
        #endregion

        #region Métodos
        public IsAvailCookie ObterCookie(ulong queryId)
        {
            if (_cookie != null)
                return _cookie;

            ChecarConexao();
            return IsAvailCookie.FromResposta(Requisicao("0 8a6e52837fc2c68f7a4a 0 " + queryId + " example.com.br"), queryId);            
        }

        protected void ChecarConexao()
        {
            if (_socket == null || !_socket.Connected)
                ConstruirConexao();
        }

        public string Requisicao(string comando, int maxRetorno = 1024)
        {
            byte[] envio = Encoding.GetEncoding("ISO-8859-1").GetBytes(comando);
            int bytesRecebidos = 0;
            string retorno = string.Empty;
            byte[] recebido = new byte[maxRetorno];
            bool recebendo = true;
            _socket.Send(envio, envio.Length, 0);

            while (recebendo)
            {
                bytesRecebidos = _socket.Receive(recebido, recebido.Length, 0);
                retorno += Encoding.GetEncoding("ISO-8859-1").GetString(recebido, 0, bytesRecebidos);
                recebendo = false;
            }
            return retorno;
        }

        public IsAvailResposta RealizarPesquisa(IsAvailQuery query)
        {
            return IsAvailResposta.FromResposta(Requisicao(query.TraduzirQuery(this)), query.Dominio);
        }
        #endregion
    }
}
